import { Axios } from 'axios'
import { AxiosRetry } from '../index'

// localStorage 存储的 key
export const LOCAL_ACCESS_KEY = 'access_token'
export const LOCAL_REFRESH_KEY = 'refresh_token'

// 请求的baseUrl
export const BASE_URL = 'http://localhost:8888'
// 路径
export const LOGIN_URL = '/login'
export const TEST_URL = '/test'
export const FETCH_TOKEN_URL = '/token'

const localStorage = {
    data: new Map(),
    setItem(k: string, v: any) {
        this.data.set(k, v)
    },
    getItem(k: string) {
        return this.data.get(k)
    }
}

const axios = new Axios({
    baseURL: BASE_URL
})

// 请求拦截：自动携带 accessToken
axios.interceptors.request.use((config) => {
    const url = config.url
    if (url !== '/login') {
        config.headers.Authorization = localStorage.getItem(LOCAL_ACCESS_KEY)
    }
    return config
})

// 响应拦截：自动解析 json 数据
axios.interceptors.response.use((res) => {
    if (res.status !== 200) {
        // console.error(res.data)
        return Promise.reject(res)
    }
    return JSON.parse(res.data)
})

const axiosRetry = new AxiosRetry({
    baseUrl: BASE_URL,
    url: FETCH_TOKEN_URL,
    unauthorizedCode: 401,
    getRefreshToken: () => localStorage.getItem(LOCAL_REFRESH_KEY),
    onSuccess: (res) => {
        const accessToken = res.data.accessToken
        localStorage.setItem(LOCAL_ACCESS_KEY, accessToken)
    },
    onError: () => {
        console.error('[AxiosRetry onError] refreshToken expired please relogin')
    }
})

const get: Axios['get'] = (url, config?) => {
    return axiosRetry.requestWrapper(() => axios.get(url, config))
}

const post: Axios['post'] = (url, config?) => {
    return axiosRetry.requestWrapper(() => axios.post(url, config))
}

const login = (): any => {
    return post(LOGIN_URL)
}
const test = (() => {
    let id = 1
    return () => get(TEST_URL, { params: { i: id++ } })
})()

// 模拟页面函数
const main = async () => {
    // 模拟登录
    const loginRes = await login()
    localStorage.setItem(LOCAL_ACCESS_KEY, loginRes.accessToken)
    localStorage.setItem(LOCAL_REFRESH_KEY, loginRes.refreshToken)

    test().then((res: any) => console.log(res.name))

    // 模拟 accessToken 失效后
    setTimeout(() => {
        test().then((res: any) => console.log(res.name))
    }, 5000)

    // 模拟 refreshToken 失效后
    setTimeout(() => {
        test().then((res: any) => console.log(res.name))
    }, 10100)
}

main()
